package com.niodata.dt.fs;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.hadoop.fs.FileStatus;

public class FileFilters {

  public static FileFilter lastModifiedBefore(Date time) {
    return new FileFilter() {
      @Override
      public boolean accept(FileStatus status) {
        return status.getModificationTime() <= time.getTime();
      }
    };
  }

  public static FileFilter lastModifiedAfter(Date time) {
    return new FileFilter() {
      @Override
      public boolean accept(FileStatus status) {
        return status.getModificationTime() >= time.getTime();
      }
    };
  }

  public static FileFilter sizeLessThan(long size) {
    return new FileFilter() {
      @Override
      public boolean accept(FileStatus status) {
        return status.getLen() <= size;
      }
    };
  }

  public static FileFilter sizeGreaterThan(long size) {
    return new FileFilter() {
      @Override
      public boolean accept(FileStatus status) {
        return status.getLen() >= size;
      }
    };
  }

  public static ChainedFileFilter chainedFileFilter(FileFilter... fileFilters) {
    return new ChainedFileFilter(fileFilters);
  }

  public static class ChainedFileFilter implements FileFilter {

    private final List<FileFilter> filters = new ArrayList<>();


    public ChainedFileFilter(FileFilter... fileFilters) {
      for (FileFilter f : fileFilters) {
        filters.add(f);
      }
    }

    @Override
    public boolean accept(FileStatus status) {
      return filters.stream().filter(f -> {
        return !f.accept(status);
      }).count() == 0;
    }

    public ChainedFileFilter lastModifiedBefore(Date time) {
      filters.add(FileFilters.lastModifiedBefore(time));
      return this;
    }

    public ChainedFileFilter lastModifiedAfter(Date time) {
      filters.add(FileFilters.lastModifiedAfter(time));
      return this;
    }

    public ChainedFileFilter sizeLessThan(long size) {
      filters.add(FileFilters.sizeLessThan(size));
      return this;
    }

    public ChainedFileFilter sizeGreaterThan(long size) {
      filters.add(FileFilters.sizeGreaterThan(size));
      return this;
    }

  }
}
